﻿using AutoMapper;
using BlazorHero.CleanArchitecture.Application.Interfaces.Repositories;
using BlazorHero.CleanArchitecture.Application.Interfaces.Services.Identity;
using BlazorHero.CleanArchitecture.Domain.Entities.Members;
using BlazorHero.CleanArchitecture.Shared.Constants.Application;
using BlazorHero.CleanArchitecture.Shared.Wrapper;
using MediatR;
using Microsoft.Extensions.Localization;
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Threading.Tasks;

namespace BlazorHero.CleanArchitecture.Application.Features.Members.Commands.AddEdit
{
    public partial class AddEditMemberCommand : IRequest<Result<long>>
    {
        public long Id { get; set; }
        [Required]
        public string UserId { get; set; }
        [Required]
        public string PhoneNumber { get; set; }
        [Required]
        public DateTime ExpirationTime { get; set; }
    }

    internal class AddEditMemberCommandHandler : IRequestHandler<AddEditMemberCommand, Result<long>>
    {
        private readonly IMapper _mapper;
        private readonly IStringLocalizer<AddEditMemberCommandHandler> _localizer;
        private readonly IUnitOfWork<long> _unitOfWork;
        private readonly IUserService _userService;

        public AddEditMemberCommandHandler(
            IUnitOfWork<long> unitOfWork, 
            IMapper mapper, 
            IStringLocalizer<AddEditMemberCommandHandler> localizer,
            IUserService userService)
        {
            _unitOfWork = unitOfWork;
            _mapper = mapper;
            _localizer = localizer;
            _userService = userService;
        }

        public async Task<Result<long>> Handle(AddEditMemberCommand command, CancellationToken cancellationToken)
        {
            var user = await _userService.GetAsync(command.UserId);
            if (user.Data == null)
            {
                return await Result<long>.FailAsync(_localizer["User Not Found"]);
            }

            if (command.Id == 0)
            {
                var member = _mapper.Map<Member>(command);
                await _unitOfWork.Repository<Member>().AddAsync(member);
                await _unitOfWork.Commit(cancellationToken);
                //await _unitOfWork.CommitAndRemoveCache(cancellationToken, ApplicationConstants.Cache.GetAllBrandsCacheKey);
                return await Result<long>.SuccessAsync(member.Id, _localizer["Member Saved"]);
            }
            else
            {               
                var member = await _unitOfWork.Repository<Member>().GetByIdAsync(command.Id);
                if (member != null)
                {
                    member.UserId = command.UserId;
                    member.PhoneNumber = command.PhoneNumber;
                    member.ExpirationTime = command.ExpirationTime;
                    await _unitOfWork.Repository<Member>().UpdateAsync(member);
                    await _unitOfWork.Commit(cancellationToken);
                    //await _unitOfWork.CommitAndRemoveCache(cancellationToken, ApplicationConstants.Cache.GetAllBrandsCacheKey);
                    return await Result<long>.SuccessAsync(member.Id, _localizer["Member Updated"]);
                }
                else
                {
                    return await Result<long>.FailAsync(_localizer["Member Not Found!"]);
                }
            }
        }
    }
}
